/*
 * @(#)FT06.java
 * Job-shop scheduling benchmark problem FT06
 */
import jp.ac.kobe_u.cs.cream.*;

public class FT06 {
    private static void ft06(Network net) {
	int n = 37;
	IntVariable v[] = new IntVariable[n];
	for (int i = 0; i < v.length; i++) {
	    v[i] = new IntVariable(net, 0, IntDomain.MAX_VALUE);
	}
	IntVariable jobs[][] = {
	    {v[1],v[2],v[3],v[4],v[5],v[6],v[0]},
	    {v[7],v[8],v[9],v[10],v[11],v[12],v[0]},
	    {v[13],v[14],v[15],v[16],v[17],v[18],v[0]},
	    {v[19],v[20],v[21],v[22],v[23],v[24],v[0]},
	    {v[25],v[26],v[27],v[28],v[29],v[30],v[0]},
	    {v[31],v[32],v[33],v[34],v[35],v[36],v[0]}
	};
	int jobs_pt[][] = {
	    {1,3,6,7,3,6},
	    {8,5,10,10,10,4},
	    {5,4,8,9,1,7},
	    {5,5,5,3,8,9},
	    {9,3,5,4,3,1},
	    {3,3,9,10,4,1}
	};
	IntVariable machines[][] = {
	    {v[2],v[11],v[16],v[20],v[29],v[34]},
	    {v[3],v[7],v[17],v[19],v[26],v[31]},
	    {v[1],v[8],v[13],v[21],v[25],v[36]},
	    {v[4],v[12],v[14],v[22],v[30],v[32]},
	    {v[6],v[9],v[18],v[23],v[27],v[35]},
	    {v[5],v[10],v[15],v[24],v[28],v[33]}
	};
	int machines_pt[][] = {
	    {3,10,9,5,3,10},
	    {6,8,1,5,3,3},
	    {1,5,5,5,9,1},
	    {7,4,4,3,1,3},
	    {6,10,7,8,5,4},
	    {3,10,8,9,4,9}
	};
	for (int j = 0; j < jobs.length; j++) {
	    new Sequential(net, jobs[j], jobs_pt[j]);
	}
	for (int m = 0; m < machines.length; m++) {
	    new Serialized(net, machines[m], machines_pt[m]);
	}
	net.setObjective(v[0]);
    }

    public static void main(String args[]) {
	Network net = new Network();
	ft06(net);

	String solverName = "para";
	int opt = Solver.MINIMIZE;
	long timeout = 180000;
	if (args.length >= 1) {
	    solverName = args[0];
	}

	Solver solver = null;
	if (solverName.equals("bb")) {
	    solver = new DefaultSolver(net, opt, "bb");
	} else if (solverName.equals("random")) {
	    solver = new LocalSearch(net, opt, "rs");
	} else if (solverName.equals("sa")) {
	    solver = new SASearch(net, opt, "sa");
	} else if (solverName.equals("ibb")) {
	    solver = new IBBSearch(net, opt, "ibb");
	} else if (solverName.equals("taboo")) {
	    solver = new TabooSearch(net, opt, "taboo");
	} else {
	    Solver sa = new SASearch((Network)net.clone(), opt, "sa");
	    Solver ibb = new IBBSearch((Network)net.clone(), opt, "ibb");
	    solver = new ParallelSolver(new Solver[] { sa, ibb });
	}
	Monitor monitor = new Monitor();
	monitor.setX(0, (int)(timeout/1000));
	solver.setMonitor(monitor);

	System.out.println("Start " + solver + ", timeout = " + timeout + " msecs");

	Solution bestSolution;
	if (true) {
	    for (solver.start(timeout); solver.waitNext(); solver.resume()) {
		Solution solution = solver.getSolution();
		int value = solution.getObjectiveIntValue();
		// System.out.println(value);
	    }
	    solver.stop();
	    bestSolution = solver.getBestSolution();
	} else {
	    bestSolution = solver.findBest(timeout);
	}

	System.out.println("Best = " + bestSolution.getObjectiveIntValue());
    }
}
